<template>
  <div>
    <div class="select" :class="[props.id ? '' : 'unselect', props.disable ? 'disable' : '']" @click="_onClick">
      <slot v-if="cur" name="name" :row="cur">
        {{ cur.name || '&nbsp;' }}
      </slot>
      <span v-else>{{ props.placeholder }}</span>
    </div>
    <el-dialog :title="props.title" v-model="show" width="54vw" append-to-body :show-close="false">
      <div class="content">
        <el-form v-if="props.searchProps.length" ref="queryForm" :model="queryParams" inline label-width="72px">
          <template v-for="(item, index) in props.searchProps" :key="index">
            <el-form-item v-if="item.type !== 'hidden'" :label="item.label" :prop="item.prop">
              <el-input
                v-if="item.type === 'input'"
                v-model="queryParams[item.prop]"
                :placeholder="item.placeholder || `请输入${item.label}`"
                :style="{width: item.width ? item.width+'px' : 'auto' }"
                clearable
                size="small"
                @keyup.enter="handleQuery"
              />
              <el-select
                v-if="item.type === 'select'"
                v-model="queryParams[item.prop]"
                :placeholder="item.placeholder || `-- 请选择${item.label} --`"
                clearable
                size="small"
                :style="{width: item.width ? item.width+'px' : 'auto' }"
                @change="handleQuery"
              >
                <el-option
                  v-for="dict in item.options"
                  :key="dict.value"
                  :label="dict.label"
                  :value="dict.value"
                />
              </el-select>
              <el-cascader
                v-if="item.type === 'cascader'"
                v-model="queryParams[item.prop]"
                :style="{width: item.width ? item.width+'px' : 'auto' }"
                :placeholder="item.placeholder || `-- 请选择${item.label} --`"
                :options="item.options"
                filterable
                clearable
                size="small"
                :props="item.props"
                @change="handleQuery"
              />
            </el-form-item>
          </template>
          <el-form-item>
            <el-button type="primary" icon="Search" size="small" @click="handleQuery">搜索</el-button>
          </el-form-item>
        </el-form>
        <el-table ref="tables" v-loading="loading" border :data="list" @row-click="handleRowClick">
          <el-table-column width="55" align="center">
            <template #default="scope">
              <input
                type="radio"
                :name="inputName"
                :value="scope.row.id"
                :checked="curSelect === scope.row.id"
              >
            </template>
          </el-table-column>
          <slot name="default" />
        </el-table>

        <el-pagination
          v-show="total > 0"
          :total="total"
          v-model:current-page="queryParams.pageIndex"
          v-model:page-size="queryParams.pageSize"
          :page-sizes="[5, 10, 15, 20]"
          layout="total, sizes, prev, pager, next, jumper"
          @size-change="getList"
          @current-change="getList"
        />
      </div>
      <template #footer>
        <span class="dialog-footer">
          <el-button type="primary" @click="submit">确 定</el-button>
          <el-button @click="show = false">取 消</el-button>
        </span>
      </template>
    </el-dialog>
  </div>
</template>

<script setup>
import { ElMessage } from 'element-plus'
import { guid } from "@/utils/index.js"

const props = defineProps({
  id: {
    type: [String, Number],
    default: undefined
  },
  disable: {
    type: Boolean,
    default: false
  },
  title: {
    type: String,
    default: '用户选择'
  },
  detailApiName: {
    type: String,
    default: 'getUser'
  },
  listApiName: {
    type: String,
    default: 'getUsers'
  },
  searchProps: {
    type: Array,
    default: () => []
  },
  placeholder: {
    type: String,
    default: '点击选择用户'
  }
})

const emit = defineEmits(['update:id', 'change'])

const inputName = ref('')
const total = ref(0)
const list = ref([])
const loading = ref(false)
const show = ref(false)
const queryParams = reactive({
  pageIndex: 1,
  pageSize: 5
})
const curSelect = ref(0)
const cur = ref({id: undefined})

const tables = ref(null)
const queryForm = ref(null)

watch(() => props.id, (newVal) => {
  if (newVal && list.value.filter(item => newVal === item.id).length === 0) {
    $xl.apis[props.detailApiName]({
      jointUrl: '/' + props.id
    }).then(res => {
      cur.value = res.data
    }).catch(err => {
      ElMessage.error(err)
    })
  } else {
    cur.value = list.value.filter(item => newVal === item.id)[0]
  }
}, { immediate: true })

watch(() => props.searchProps, (newVal) => {
  newVal.forEach(item => {
    queryParams[item.prop] = item.default
  })
}, { immediate: true, deep: true })

onMounted(() => {
  inputName.value = guid(16)
})

const getList = () => {
  loading.value = true
  $xl.apis[props.listApiName]({
    params: queryParams
  }).then(res => {
    list.value = res.data.records
    total.value = res.data.total
    const curArr = list.value.filter(item => props.id === item.id)
    cur.value = curArr.length ? curArr[0] : undefined
    loading.value = false
  })
}

const handleRowClick = (row) => {
  curSelect.value = row.id
}

const handleQuery = () => {
  queryParams.pageIndex = 1
  getList()
}

const resetQuery = () => {
  queryParams.pageIndex = 1
  queryParams.pageSize = 5
  props.searchProps.forEach(item => {
    queryParams[item.prop] = item.default
  })
  getList()
}

const submit = () => {
  const curArr = list.value.filter(item => curSelect.value === item.id)
  cur.value = curArr.length ? curArr[0] : undefined
  emit('update:id', curSelect.value)
  emit('change', cur.value)
  show.value = false
}

const _onClick = () => {
  if (!props.disable) {
    show.value = true
  }
  if (!show.value) return
  curSelect.value = props.id
  resetQuery()
}
</script>

<style lang="scss" scoped>
.select {
  background-color: #fff;
  display: flex;
  align-items: center;
  border: 1px solid #e5e7ec;
  border-radius: 4px;
  padding: 0 16px;
  cursor: pointer;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;

  &:hover {
    background-color: #f5f7fa;
  }
}

.disable {
  cursor: not-allowed;
  background-color: #f5f7fa;
}

.unselect {
  color: #c0c4cc;
}
</style>
